When we talk about Message Exchange Patterns,
or MEPs, we're considering the direction and timing of data between the
client and service. How do I get into the bus and what are the
implications of those choices? Let's discuss the four primary options.
Request/Response services
This
is probably the pattern that's most familiar to you. We're all
comfortable making a function call to a component and waiting for a
response. When a service uses this pattern, it's frequently performing a remote procedure call
where the caller accesses functionality on the distant service and is
blocked until either a timeout occurs or until the receiver sends a
response that is expected by the caller.
As
we'll see below, while this pattern may set developers at ease, it may
encourage bad behavior. Nevertheless, the cases where request/response
services make the most sense are fine-grained functions and mashup
services. If you need a list of active contracts that a hospital has
with your company, then a request/response operation fits best. The
client application should wait until that response is received before
moving on to the next portion of the application. Or, let's say my web
portal is calling an aggregate service, which takes contact data from
five different systems and mashes them up into a single data entity
that is then returned to the caller. This data is being requested for
immediate presentation to an end user, and thus it's logical to solicit
information from a service and wait to draw the screen until the
completed result is loaded.
BizTalk
Server 2009 has full support for both consuming and publishing services
adhering to a request/response pattern. When exposing request/response
operations through BizTalk orchestrations, the orchestration port's
Communication Pattern is set to Request-Response and the Port direction of communication is equal to I'll be receiving a request and sending a response.
Once this orchestration port is bound to a physical request/response
receive port, BizTalk takes care of correlating the response message
with the appropriate thread that made the request. This is significant
because by default, BizTalk is a purely asynchronous messaging engine.
Even when you configure BizTalk Server to behave in a request/response
fashion, it's only putting a facade on the standard underlying
plumbing. A synchronous BizTalk service interface actually sits on top
of a sophisticated mechanism of correlating MessageBox communication to
simulate a request/response pattern.
When
consuming request/response services from BizTalk from an orchestration,
the orchestration port's Communication Pattern is set to Request-Response and the Port direction of communication is equal to I'll be sending a request and receiving a response.
The corresponding physical send port uses a solicit-response pattern
and allows the user to set up both pipelines and maps for the inbound
and outbound messages.
One
concern with either publishing or consuming request/response services
is the issue of blocking and timeouts. From a BizTalk perspective, this
means that whenever you publish an orchestration as a request/response
service, you should always verify that the logic residing between
inbound and outbound transmissions will either complete or fail within
a relatively brief amount of time. This dictates wrapping this logic
inside an orchestration Scope shape with a preset timeout that is longer than the standard web service timeout interval.
For
consuming services, a request/response pattern forces the orchestration
to block and wait for the response to be returned. If the service
response isn't necessary for processing to continue, consider using a Parallel
shape that isolates the service interaction pattern on a dedicated
branch. This way, the execution of unrelated workflow steps can proceed
even though the downstream service is yet to respond.